package com.syh.jn.scm.infrastructure.repository.impl.supplier.stock;

import cn.redscarf.commons.util.other.ExtStringUtils;
import cn.redscarf.commons.wrapper.Restrictions;
import cn.redscarf.commons.wrapper.Wrapper;
import com.syh.core.ddd.infrastructure.repository.AggregateRepoMybatisImplTmpl;
import com.syh.jn.scm.domain.supplier.entity.stock.StockOtherInBill;
import com.syh.jn.scm.domain.supplier.entity.stock.StockOtherInBillItem;
import com.syh.jn.scm.domain.supplier.repository.stock.StockOtherInBillReadRepository;
import com.syh.jn.scm.dto.supplier.stock.StockOtherInBillItemVo;
import com.syh.jn.scm.dto.supplier.stock.StockOtherInBillVo;
import com.syh.jn.scm.infrastructure.repository.model.base.StorehouseModel;
import com.syh.jn.scm.infrastructure.repository.model.stock.stockOtherInBill.StockOtherInBillItemModel;
import com.syh.jn.scm.infrastructure.repository.model.stock.stockOtherInBill.StockOtherInBillModel;
import com.syh.jn.scm.infrastructure.repository.utils.MybatisTemplate;
import com.syh.jn.scm.infrastructure.repository.utils.SQLAliasGenerateUtil;
import com.syh.jn.scm.infrastructure.wrapper.BaseResolve;
import com.syh.jn.scm.infrastructure.wrapper.ResolveToSQL;
import lombok.extern.java.Log;
import org.apache.ibatis.jdbc.SQL;
import org.springframework.stereotype.Repository;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 其他出入库
 */
@Log
@Repository("stockOtherInBillReadRepositoryMbImpl")
public class StockOtherInBillReadRepositoryMbImpl implements StockOtherInBillReadRepository {

  private AggregateRepoMybatisImplTmpl<StockOtherInBillVo, StockOtherInBillModel, Long> billTmpl =
          new AggregateRepoMybatisImplTmpl.Builder()
                  .listTypeClass(StockOtherInBillVo.class)
                  .modelClass(StockOtherInBillModel.class).build();
  private AggregateRepoMybatisImplTmpl<StockOtherInBillItemVo, StockOtherInBillItemModel, Long> itemTmpl =
          new AggregateRepoMybatisImplTmpl.Builder()
                  .listTypeClass(StockOtherInBillItemVo.class)
                  .modelClass(StockOtherInBillItemModel.class).build();


  @Override
  public StockOtherInBillVo getById(Long aLong) {
    return billTmpl.getById(aLong);
  }

  @Override
  public StockOtherInBill getById(Long id, boolean haveItems) {
    log.warning("该接口暂不实现");
    return null;
  }

  @Override
  public StockOtherInBillItem getItemByItemId(Long id) {
    log.warning("该接口暂不实现");
    return null;
  }

  @Override
  public StockOtherInBillVo getOne(Wrapper wrapper) {
    return billTmpl.getOne(wrapper);
  }

  @Override
  public boolean contains(Long aLong) {
    return this.billTmpl.contains(aLong);
  }

  @Override
  public List<StockOtherInBillVo> getList(Wrapper wrapper) {
    return this.billTmpl.getList(wrapper);
  }

  @Override
  public List<StockOtherInBillVo> findListPage(Wrapper wrapper, Integer startRow, Integer count) {
    return this.billTmpl.findListPage(wrapper, startRow, count);
  }

  @Override
  public int getCount(Wrapper wrapper) {
    StringBuffer sqlSb = new StringBuffer();
    String viewSql = this.billTmpl.getQuerySql().toString();
    String viewSqlAry[] = viewSql.split("\\s*FROM\\s*");
    sqlSb.append("SELECT COUNT(DISTINCT stockOtherIn.ID) AS COUNT FROM ");
    for (int i = 1; i <= viewSqlAry.length - 1; i++) {
      if (i > 1) {
        sqlSb.append(" FROM ").append(viewSqlAry[i]);
      } else {
        sqlSb.append(viewSqlAry[i]);
      }
    }
    BaseResolve resolveToSQL = new ResolveToSQL(wrapper, this.billTmpl.getWrapperParseMethods());
    sqlSb.append(" WHERE 1=1 ");
    sqlSb.append(resolveToSQL.resolve());

    Map resultM = MybatisTemplate.selectOne(sqlSb.toString());
    return Integer.parseInt(resultM.get("COUNT").toString());
  }

  @Override
  public List<StockOtherInBillItemVo> findStockOtherInBillItemVoByBillId(Long stockOtherInBillId) {
    Wrapper wrapper = Wrapper.build().append(Restrictions.eq("stockOtherInBillId", stockOtherInBillId));
    return this.itemTmpl.getList(wrapper);
  }

  @Override
  public List<StockOtherInBillItemVo> findStockOtherInBillItemVoListPage(Wrapper wrapper, Integer startRow, Integer count) {
    return this.itemTmpl.findListPage(wrapper, startRow, count);
  }

  @Override
  public int findStockOtherInBillItemVoCount(Wrapper wrapper) {
    return this.itemTmpl.getCount(wrapper);
  }

  public StockOtherInBillReadRepositoryMbImpl() {
    // 初始化查询语句 stockOtherInBill
    {
      SQL stockOtherInBillSql = new SQL() {{
        SELECT(
                "DISTINCT stockOtherIn.ID",
                SQLAliasGenerateUtil.aliasGenerate(StockOtherInBillModel.class,
                        "stockOtherIn", null),
                "storehouse.NAME AS storehouseName",
                "account.NAME AS operatorName"
        );
        FROM("T_STOCK_OTHER_IN_BILL stockOtherIn");
        LEFT_OUTER_JOIN(
                "T_BASE_STOREHOUSE storehouse on stockOtherIn.STOREHOUSE_ID = storehouse.ID"
        );
        LEFT_OUTER_JOIN(
                "T_SYSTEM_ACCOUNT account on stockOtherIn.OPERATOR_ID = account.ID"
        );
        LEFT_OUTER_JOIN("T_STOCK_OTHER_IN_BILL_ITEM item ON item.STOCK_OTHER_IN_BILL_ID = stockOtherIn.ID");
      }};
      this.billTmpl.setQuerySql(stockOtherInBillSql);
      //初始化查询条件解析 stockOtherInBillMap
      final HashMap<String, String> stockOtherInBillMap = new HashMap<>();
      stockOtherInBillMap.put("id", "stockOtherIn.ID");
      stockOtherInBillMap.put("code", "stockOtherIn.CODE");
      stockOtherInBillMap.put("status", "stockOtherIn.STATUS");
      stockOtherInBillMap.put("inputDateTimestamp", "stockOtherIn.INPUT_DATE_TIMESTAMP");
      stockOtherInBillMap.put("storehouseId", "stockOtherIn.STOREHOUSE_ID");
      stockOtherInBillMap.put("businessEntityId", "stockOtherIn.BUSINESS_ENTITY_ID");
      stockOtherInBillMap.put("goodsId", "item.GOODS_ID");
      stockOtherInBillMap.put("goodsName", "item.GOODS_NAME");
      this.billTmpl.setWrapperParseMethods((propertyName) -> {
        return stockOtherInBillMap.get(propertyName);
      });
    }

    // stockOtherInBillItem
    {
      String stockOtherInBillTable = this.billTmpl.getModelTableName(StockOtherInBillModel.class);
      String stockOtherInBillItemTable = this.billTmpl.getModelTableName(StockOtherInBillItemModel.class);
      String storehouseTable = this.billTmpl.getModelTableName(StorehouseModel.class);
      SQL stockOtherInBillItemSql = new SQL() {{
        SELECT(
                SQLAliasGenerateUtil.aliasGenerate(StockOtherInBillItemModel.class, "stockOtherInItem", null),
                "storehouse.NAME as storehouseName"
        );
        FROM(
                ExtStringUtils.buildString(stockOtherInBillItemTable, " stockOtherInItem")
        );
        INNER_JOIN(
                ExtStringUtils.buildString(stockOtherInBillTable, " stockOtherIn on stockOtherInItem.STOCK_OTHER_IN_BILL_ID = stockOtherIn.ID")
        );
        LEFT_OUTER_JOIN(
                ExtStringUtils.buildString(storehouseTable + " storehouse on stockOtherIn.STOREHOUSE_ID = storehouse.ID")
        );
      }};
      this.itemTmpl.setQuerySql(stockOtherInBillItemSql);
      //初始化查询条件解析 stockInItemMap
      final HashMap<String, String> stockInItemMap = new HashMap<>();
      stockInItemMap.put("id", "stockOtherInItem.ID");
      stockInItemMap.put("stockOtherInBillId", "stockOtherInItem.STOCK_OTHER_IN_BILL_ID");
      stockInItemMap.put("status", "stockOtherIn.STATUS");
      stockInItemMap.put("inputDateTimestamp", "stockOtherIn.INPUT_DATE_TIMESTAMP");
      stockInItemMap.put("storehouseId", "stockOtherIn.STOREHOUSE_ID");
      stockInItemMap.put("businessEntityId", "stockOtherIn.BUSINESS_ENTITY_ID");
      this.itemTmpl.setWrapperParseMethods((propertyName) -> {
        return stockInItemMap.get(propertyName);
      });
    }


  }
}
